package com.javacv.plus.extensions.image;

import com.javacv.plus.core.config.ProcessorConfig;
import com.javacv.plus.core.processor.MediaProcessor;
import com.javacv.plus.core.processor.ProcessorContext;
import com.javacv.plus.extensions.image.config.ImageConfig;
import com.javacv.plus.extensions.image.steps.*;
import lombok.extern.slf4j.Slf4j;
import org.bytedeco.opencv.opencv_core.Mat;

import java.io.File;

/**
 * 图像处理器
 * 提供简化的链式调用API
 */
@Slf4j
public class ImageProcessor extends MediaProcessor<ImageProcessor, ProcessorResult> {

    private Mat sourceImage;

    protected ImageProcessor(ProcessorConfig config) {
        super(config);
    }

    /**
     * 创建图像处理器
     */
    public static ImageProcessor of(String imagePath) {
        ImageConfig config = new ImageConfig();
        config.setInputPath(imagePath);
        
        ImageProcessor processor = new ImageProcessor(config);
        processor.addStep(new LoadImageStep());
        return processor;
    }

    /**
     * 创建图像处理器（自定义配置）
     */
    public static ImageProcessor of(String imagePath, ImageConfig config) {
        config.setInputPath(imagePath);
        
        ImageProcessor processor = new ImageProcessor(config);
        processor.addStep(new LoadImageStep());
        return processor;
    }

    /**
     * 调整图像大小
     */
    public ImageProcessor resize(int width, int height) {
        return addStep(new ResizeStep(width, height));
    }

    /**
     * 按比例缩放
     */
    public ImageProcessor scale(double factor) {
        return addStep(new ScaleStep(factor));
    }

    /**
     * 添加模糊效果
     */
    public ImageProcessor blur(int kernelSize) {
        return addStep(new BlurStep(kernelSize));
    }

    /**
     * 旋转图像
     */
    public ImageProcessor rotate(double angle) {
        return addStep(new RotateStep(angle));
    }

    /**
     * 添加水印
     */
    public ImageProcessor addWatermark(String watermarkPath) {
        return addStep(new WatermarkStep(watermarkPath));
    }

    /**
     * 添加文字水印
     */
    public ImageProcessor addTextWatermark(String text) {
        return addStep(new TextWatermarkStep(text));
    }

    /**
     * 调整亮度
     */
    public ImageProcessor brightness(double factor) {
        return addStep(new BrightnessStep(factor));
    }

    /**
     * 调整对比度
     */
    public ImageProcessor contrast(double factor) {
        return addStep(new ContrastStep(factor));
    }

    /**
     * 转换为灰度图
     */
    public ImageProcessor grayscale() {
        return addStep(new GrayscaleStep());
    }

    /**
     * 裁剪图像
     */
    public ImageProcessor crop(int x, int y, int width, int height) {
        return addStep(new CropStep(x, y, width, height));
    }

    /**
     * 添加边框
     */
    public ImageProcessor addBorder(int size, int r, int g, int b) {
        return addStep(new BorderStep(size, r, g, b));
    }

    /**
     * 应用滤镜效果
     */
    public ImageProcessor applyFilter(FilterStep.FilterType filterType, double intensity) {
        return addStep(new FilterStep(filterType, intensity));
    }

    /**
     * 高斯模糊
     */
    public ImageProcessor gaussianBlur(double intensity) {
        return addStep(new FilterStep(FilterStep.FilterType.GAUSSIAN_BLUR, intensity));
    }

    /**
     * 中值模糊
     */
    public ImageProcessor medianBlur(double intensity) {
        return addStep(new FilterStep(FilterStep.FilterType.MEDIAN_BLUR, intensity));
    }

    /**
     * 双边滤波
     */
    public ImageProcessor bilateralFilter(double intensity) {
        return addStep(new FilterStep(FilterStep.FilterType.BILATERAL, intensity));
    }

    /**
     * Canny边缘检测
     */
    public ImageProcessor cannyEdge(double intensity) {
        return addStep(new FilterStep(FilterStep.FilterType.CANNY, intensity));
    }

    /**
     * 水平翻转
     */
    public ImageProcessor flipHorizontal() {
        return addStep(new FlipStep(FlipStep.FlipType.HORIZONTAL));
    }

    /**
     * 垂直翻转
     */
    public ImageProcessor flipVertical() {
        return addStep(new FlipStep(FlipStep.FlipType.VERTICAL));
    }

    /**
     * 水平垂直翻转
     */
    public ImageProcessor flipBoth() {
        return addStep(new FlipStep(FlipStep.FlipType.BOTH));
    }

    /**
     * 直方图均衡化
     */
    public ImageProcessor equalizeHistogram() {
        return addStep(new ColorAdjustStep(ColorAdjustStep.AdjustType.HISTOGRAM_EQUALIZATION, 1.0));
    }

    /**
     * 保存图像
     */
    public ProcessorResult save(String outputPath) {
        getConfig().setOutputPath(outputPath);
        addStep(new SaveImageStep());
        return process();
    }

    /**
     * 保存为指定格式
     */
    public ProcessorResult saveAs(String outputPath, String format) {
        getConfig().setOutputPath(outputPath);
        getConfig().setProperty("format", format);
        addStep(new SaveImageStep());
        return process();
    }

    /**
     * 获取处理结果但不保存
     */
    public ProcessorResult get() {
        return process();
    }

    @Override
    protected ProcessorResult executeProcess() throws Exception {
        ProcessorContext context = new ProcessorContext();
        
        // 执行处理链
        chain.execute(this, context);
        
        // 创建结果
        ProcessorResult result = new ProcessorResult();
        result.setSourcePath(getConfig().getInputPath());
        result.setOutputPath(getConfig().getOutputPath());
        result.setProcessedImage(context.getAttribute("processedImage"));
        result.setSuccess(true);
        
        return result;
    }

    /**
     * 获取图像配置
     */
    public ImageConfig getImageConfig() {
        return (ImageConfig) getConfig();
    }

    /**
     * 设置源图像（内部使用）
     */
    public void setSourceImage(Mat sourceImage) {
        this.sourceImage = sourceImage;
    }

    /**
     * 获取源图像（内部使用）
     */
    public Mat getSourceImage() {
        return sourceImage;
    }

    /**
     * 检查输入文件是否存在
     */
    @Override
    protected void beforeProcess() {
        super.beforeProcess();
        
        String inputPath = getConfig().getInputPath();
        if (inputPath != null && !new File(inputPath).exists()) {
            throw new IllegalArgumentException("输入文件不存在: " + inputPath);
        }
    }
} 